package com.zmn.oms.zmn.business.impl.message;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.oms.business.interfaces.messageV1.common.MessageGetSendInfoService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dto.OmsBaseOperator;
import com.zmn.oms.common.dto.OmsRefundRequestDTO;
import com.zmn.oms.common.enums.RefundInitiateTypeEnum;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.work.modify.OrderDistributeDTO;
import com.zmn.oms.model.dto.work.modify.OrderWarrantyUpdateDTO;
import com.zmn.oms.model.dto.work.refund.RefundDTO;
import com.zmn.oms.model.dto.work.refund.RefundVoucherDTO;
import com.zmn.oms.model.dto.work.refund.WorkRefundResultDTO;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.zmn.business.interfaces.message.SendOrderNodeMsgService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class SendOrderNodeMsgServiceImpl implements SendOrderNodeMsgService {
    private Logger logger = LoggerFactory.getLogger(SendOrderNodeMsgServiceImpl.class);
    @Autowired
    private MessageGetSendInfoService messageGetSendInfoService;
    @Resource
    private ZmnMQSender zmnMQSender;

    @Override
    public void notice(OrderLog orderLog, OrderWork dbOrderWork, OmsBaseOperator omsBaseOperator, Object proceed) {
        // 自动触发，判断节点是否开启
        if (!MessageControlSwitchConsts.noticeAllTypes.contains(orderLog.getType())) {
            return;
        }

        logger.info("#OMS#sendMessage#orderId={}自动发送节点{}消息", orderLog.getOrderId(), orderLog.getType());
        Integer plat = dbOrderWork.getPlatWork();
        Integer nodeMark = orderLog.getType();
        switch (orderLog.getType()) {
            // 平台指派 因为无分单 - 组装自动触发分单
            case OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE:
                if (omsBaseOperator instanceof OrderDistributeDTO) {
                    OrderDistributeDTO distributeDTO = (OrderDistributeDTO) omsBaseOperator;
                    boolean platWay = Objects.equals(OrderDistributeConsts.DISTRIBUTE_WAY_PLAT, distributeDTO.getDistributeWay());
                    if (platWay) {
                        nodeMark = OrderLogConsts.ORDER_LOG_TYPE_ASSIGN;
                    }
                }
                break;
            // 工单取消
            case OrderLogConsts.ORDER_LOG_TYPE_CANCEL:
                // 若转单订单，未领单之前发送下单平台短信内容，领单后，发送服务平台短信
                boolean isTurn = !Objects.equals(dbOrderWork.getPlat(), dbOrderWork.getPlatWork());
                if (isTurn && dbOrderWork.getStatus() < OrderStatusConsts.WORK_STATUS_TAKE) {
                    plat = dbOrderWork.getPlat();
                }
                break;
            // 工单未完成或工单不存在保修卡则不发送保修卡
            // 需求不发送保修卡和延保
//            case OrderLogConsts.ORDER_LOG_TYPE_WARRANTY:
//                if (Objects.isNull(orderWork.getCompleteTime())) {
//                    return;
//                }
//                String warrantyCode = messageGetSendInfoService.checkWarrantyAndGetWarrantyCode(orderWork.getOrderId());
//                if (StringUtils.isBlank(warrantyCode)) {
//                    return;
//                }
//                break;
//            case OrderLogConsts.ORDER_LOG_TYPE_COMPLETE:
//                //  啄木鸟和川南订单 完成节点 同时 发送保修卡信息
//                boolean isSendWarranty = Lists.newArrayList(GlobalConsts.PLAT_MARK_ZMN, GlobalConsts.PLAT_MARK_CNHB).contains(plat);
//                if (isSendWarranty) {
//                    // 判断是否有保修卡及获取保修卡号
//                    String warrantyCode1 = messageGetSendInfoService.checkWarrantyAndGetWarrantyCode(orderWork.getOrderId());
//                    if (StringUtils.isNotBlank(warrantyCode1)) {
//                        submitOrderMsg(orderWork.getWorkId(), orderWork.getOrderId(), OrderLogConsts.ORDER_LOG_TYPE_WARRANTY, plat, null);
//                    }
//                }
//                break;
            case OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT:
                // 退款结果!=退款成功 || 没退完 (不发消息)
                WorkRefundResultDTO workRefundResultDTO = ((WorkRefundResultDTO) omsBaseOperator);
                if (!Objects.equals(PayConsts.REFUND_STATUS_DONE, workRefundResultDTO.getRefundResultDTO().getStatus())
                        || !Objects.equals(workRefundResultDTO.getAllRefund(), GlobalConsts.YES)) {
                    return;
                }
                break;
            default:
                break;
        }

        // 处理其他参数（数据格式示例：{"param0":"000","param1":"示例"}）
        String remark = null;
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_UPDATE_WARRANTY, orderLog.getType())) {
            remark = addWarranty(omsBaseOperator);
        } else if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT, orderLog.getType())) {
            remark = addRefundResult(omsBaseOperator);
        }

        // 提交发送消息到队列
        submitOrderMsg(dbOrderWork.getWorkId(), dbOrderWork.getOrderId(), orderLog.getType(), nodeMark, plat, remark);
    }

    private String addRefundResult(OmsBaseOperator omsBaseOperator) {
        if (omsBaseOperator instanceof OrderWarrantyUpdateDTO) {
            WorkRefundResultDTO workRefundResultDTO = ((WorkRefundResultDTO) omsBaseOperator);
            String requestData = workRefundResultDTO.getRefundResultDTO().getRequestData();
            OmsRefundRequestDTO omsRefundRequestDTO = JSON.parseObject(requestData, OmsRefundRequestDTO.class);
            if (Objects.equals(omsRefundRequestDTO.getRefundInitiateType(), RefundInitiateTypeEnum.REFUND_DIFFERENCE.getType())) {
                Map<String, Integer> map = new HashMap<>();
                map.put("refundAmount", workRefundResultDTO.getRefundResultDTO().getRefundAmount());
                return JSON.toJSONString(map);
            }
        }
        return null;
    }

    /**
     * 处理延保消息参数
     *
     * @param omsOperator
     * @return
     */
    private String addWarranty(OmsBaseOperator omsOperator) {
        if (omsOperator instanceof OrderWarrantyUpdateDTO) {
            OrderWarrantyUpdateDTO warrantyDTO = (OrderWarrantyUpdateDTO) omsOperator;
            Map<String, String> map = new HashMap<>();
            map.put("warrantyAddDay", String.valueOf(warrantyDTO.getAddDay()));
            return JSON.toJSONString(map);
        }
        return null;
    }

    private String addRefundAmount(Integer type, OmsBaseOperator omsBaseOperator) {
        Map<String, String> map = new HashMap<>();
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_REFUND_VOUCHER, type)) {
            RefundVoucherDTO refundVoucherDTO = (RefundVoucherDTO) omsBaseOperator;
//            map.put("refund_amount", NumberUtil.convertMoneyToYuan2(refundVoucherDTO.getAmount()));
        } else if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_REFUND, type)) {
            RefundDTO refundDTO = (RefundDTO) omsBaseOperator;
            map.put("refund_amount", NumberUtil.convertMoneyToYuan2(refundDTO.getRefundAmount()));
        } else {
            return null;
        }

        return JSON.toJSONString(map);
    }

    /**
     * 发送消息mq
     *
     * @param workId   必须    工单号
     * @param orderId  必须    订单号
     * @param nodeMark 必须    节点标示（工单日志类型）
     * @param plat     必须    平台标示
     * @return
     */
    @Override
    public void submitOrderMsg(Long workId, Long orderId, Integer logType, Integer nodeMark, Integer plat, String remark) {
        // 特殊处理 啄木鸟平台需3分钟后发上门送消息
        Integer timeMillis = 2000;
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_VISIT, nodeMark) && Objects.equals(GlobalConsts.PLAT_MARK_ZMN, plat)) {
            timeMillis = 1000 * 60 * 3;
        }

        // 完成节点消息随机延迟15~20分钟发送
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_COMPLETE, nodeMark)) {
            int millis = (int) (15 + Math.random() * (20 - 15 + 1));// 随机15-20
            timeMillis = 1000 * 60 * millis;
        }

        // 上门超时，延迟30分钟发送 迟到安抚消息
        if (Objects.equals(MessageRuleIdConsts.MESSAGE_GLOBAL_VISIT_TIME_OUT_NODE_MARK, nodeMark)) {
            timeMillis = 1000 * 60 * 30;
        }

        JSONObject msgJsonObject = new JSONObject();
        msgJsonObject.put("orderId", orderId);
        msgJsonObject.put("workId", workId);
        msgJsonObject.put("plat", plat);
        msgJsonObject.put("nodeMark", nodeMark);
        msgJsonObject.put("logType", logType);
        msgJsonObject.put("remark", remark);

        // 延迟2秒执行 防止未提交事物 or 同步到es
        long time = System.currentTimeMillis() + timeMillis;
        String message = JSON.toJSONString(msgJsonObject);
        String key = String.format("%s-%s", orderId, nodeMark);
        logger.info("#oms#orderId={}发送消息mq消息start==========", JSON.toJSONString(msgJsonObject));
        zmnMQSender.sendWithStartDeliverTime(MessageQueueTopicConstant.ZMN_TOPIC_OMS, OmsMqTagConsts.ZMN_TOPIC_OMS_ORDER_SEND_MESSAGE_NODE_MQ_TAGS, key, message, time);

        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_COMPLETE, nodeMark)) {
            // 完成节点，发送调查问卷，在原时间基础上延迟20分钟发送
            timeMillis = timeMillis + 1000 * 60 * 20;
            time = System.currentTimeMillis() + timeMillis;
            logger.info("#oms#orderId={}发送消息mq消息-调查问卷-start==========", JSON.toJSONString(msgJsonObject));
            zmnMQSender.sendWithStartDeliverTime(MessageQueueTopicConstant.ZMN_TOPIC_OMS, OmsMqTagConsts.ZMN_TOPIC_TAG_OMS_ORDER_SEND_MESSAGE_QUESTIONNAIRE,
                    String.format("questionnaire-%s-%s", orderId, nodeMark), message, time);
        }
    }

}
